package com.dating.core;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.beetl.ext.nutz.BeetlViewMaker;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.ChainBy;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.IocBy;
import org.nutz.mvc.annotation.Modules;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.annotation.SetupBy;
import org.nutz.mvc.annotation.Views;
import org.nutz.mvc.ioc.provider.ComboIocProvider;

import com.dating.base.bean.User;
import com.dating.base.dto.Menu;
import com.dating.base.service.ShiroUserService;
import com.dating.base.service.UserService;
import com.dating.base.vo.SystemSetting;
import com.dating.core.entries.Result;
import com.dating.core.ext.BaseModule;
import com.dating.utils.CaptchaUtil;
import com.dating.utils.DateTools;
import com.dating.utils.StrKit;

@IocBy(type = ComboIocProvider.class, args = { "*js", "ioc/","*anno",
		"com.dating", "*tx" })
@Modules(packages = { "com.dating" })
@ChainBy(args = "mvc/nutz-mvc-chain.js")
@Views(BeetlViewMaker.class)
@SetupBy(value = MainSetup.class)
@Filters
public class MainModule extends BaseModule {

	private static final Log log = Logs.get();
	
	private static final String CAPTCHA_KEY = "captcha";
	
	@Inject
	private UserService userService ;
	
	@Inject
	private ShiroUserService shiroUserService ;
	
	@Override
	public String _getNameSpace() {
		return "main";
	}
	
	@At
	public Result hello() {
		return Result.success().addData("msg", "Hello").addData("ip", _ip());
	}
	

	@At("/")
	@Ok("re:beetl:templates/pages/login.html")
	public String index() {
		log.debugf("[%s][%s] login %s ",DateTools.format(DateTools.getNow(), DateTools.yyyy_MM_dd_HH_mm_ss), _ip() , _ua());
		Subject subject = SecurityUtils.getSubject();
		if(subject != null && subject.isAuthenticated()){
			return "beetl:templates/pages/index.html";
		}else{
			return null;
		}
	}

	@At
	@Ok("raw:png")
	public Object captcha(HttpSession session,HttpServletResponse response , @Param("w") int w  , @Param("h") int h) {  
        //生成随机字串  
        String verifyCode = CaptchaUtil.generateVerifyCode(4);  
        //存入会话session  
        session.setAttribute(CAPTCHA_KEY, verifyCode.toLowerCase());  
        //生成图片 
        w = w == 0 ? 200 : w ;
        h = h == 0 ? 80  : h ;
        try {
			CaptchaUtil.outputImage(w, h, response.getOutputStream(), verifyCode);
		} catch (IOException e) {
			log.error(e);
		}
        return null;
	}
	
	/**
	 * 用户登录
	 * @param currUser
	 * @return
	 */
	@At("login")
	@Ok("json")
	public Result doLogin(@Param("..") User user) { 
		
		//验证码验证
		String authCode = getPara("authCode");
		if(StrKit.isBlank(authCode) || !(authCode.toLowerCase()
				.equals(Mvcs.getReq().getSession().getAttribute(CAPTCHA_KEY)))){
			return Result.fail("输入的验证码有误！");
		}
		//进行shiro认证
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(
				user.getName(), user.getPassword());
		token.setRememberMe(getParaToBoolean("remember", false));
		try {
			//登录认证
			subject.login(token);
			
			//登录用户和拥有菜单
			user = userService.getUser(user.getName());
			List<Menu> menus = userService.getMenus(user.getId());
			
			Mvcs.getReq().getSession().setAttribute(SystemSetting.SESSION_USER_KEY, user);
			Mvcs.getReq().getSession().setAttribute("userMenus", menus);
			
			return Result.success().addData("msg", "用户登录成功！");
		} catch (LockedAccountException e) { 
			return Result.fail("用户已被锁定！");
		} catch (IncorrectCredentialsException e){
			log.errorf("用户登录失败！%s" , e.getMessage());
			return Result.fail("用户名或密码错误！");
		} catch (Exception e) {
			log.error(e);
			log.errorf("用户登录失败！%s" , e.getMessage());
			return Result.fail("用户登录失败！");
		}
		
	}
	
	
	@At
	@Ok("beetl:templates/pages/index.html")
	public Result main(){
		return Result.success();
	}
	
	
	@At
	@Ok("json")
	public Result loginOut() {
		Subject user = SecurityUtils.getSubject();
		String uname = user.getPrincipal().toString();
		try {
			user.logout();
			log.debugf("%s [%s] 退出系统！", DateTools.format(DateTools.getNow(), DateTools.yyyy_MM_dd_HH_mm_ss), uname);
		} catch (Exception e) {
			log.debugf("%s [%s] 退出系统！异常 ,%s ", DateTools.format(DateTools.getNow(), DateTools.yyyy_MM_dd_HH_mm_ss),uname, e.getMessage());
			log.error(e);
		}
		return Result.success();
	}
}
